<!--
 * @Descripttion: 
 * @Author: Kevin
 * @Date: 2022-06-14 10:58:57
 * @LastEditors: Tommy Chen
 * @LastEditTime: 2024-08-14
-->
<template>
  <div>
    <a-form-model
      :labelCol="{ span: 10 }"
      :wrapperCol="{ span: 14 }"
      labelAlign="left"
      :model="sourceForm"
      ref="sourceFormRef"
      :rules="formRuleObj"
      :colon="false"
      style="width: 600px"
    >
      <a-form-model-item :label="$t('common.status')">
        <a-switch v-model="sourceForm.statusBool" />
        <span style="margin-left: 8px">{{ statusTxt }}</span>
      </a-form-model-item>
      <div v-show="sourceForm.statusBool">
        <a-form-model-item prop="name" :label="$t('thirdPart.sourceName')">
          <a-input v-model="sourceForm.name" />
        </a-form-model-item>
        <a-form-model-item :label="$t('common.type')" prop="type">
          <a-radio-group v-model="sourceForm.type">
            <a-radio value="ad">
              <span class="source-type ad">{{ $t('thirdPart.ad') }}</span>
            </a-radio>
            <a-radio value="ldap">
              <span class="source-type ldap">{{ $t('thirdPart.ldap') }}</span>
            </a-radio>
          </a-radio-group>
        </a-form-model-item>
        <template v-if="sourceForm.type === 'ad'">
          <a-form-model-item
            prop="serverDomain"
            :label="$t('thirdPart.adName')"
          >
            <a-input v-model="sourceForm.serverDomain" />
          </a-form-model-item>
          <a-form-model-item
            prop="serverIp"
            :label="$t('thirdPart.primaryDnsIp')"
          >
            <a-input v-model="sourceForm.serverIp" />
          </a-form-model-item>
          <a-form-model-item
            prop="serverPort"
            :label="$t('thirdPart.serverPort')"
          >
            <a-input v-model="sourceForm.serverPort" />
          </a-form-model-item>
        </template>
        <template v-else>
          <a-form-model-item
            prop="ldapIp"
            :label="$t('thirdPart.ldapServerIp')"
          >
            <a-input v-model="sourceForm.ldapIp" />
          </a-form-model-item>
          <a-form-model-item
            prop="ldapPort"
            :label="$t('thirdPart.ldapServerPort')"
          >
            <a-input v-model="sourceForm.ldapPort" />
          </a-form-model-item>
          <a-form-model-item prop="rootDn" :label="$t('thirdPart.rootNodeDn')">
            <a-input
              v-model="sourceForm.rootDn"
              ref="rootDnRef"
              :placeholder="$t('thirdPart.rootDnPh')"
            />
            <a-button
              v-show="sourceForm.type === 'ldap'"
              @click="onGetDn"
              type="primary"
              ghost
              class="conn-test-btn"
              :loading="isLoading"
            >
              {{ $t('thirdPart.getDn') }}
            </a-button>
          </a-form-model-item>
        </template>

        <!-- 绑定账号 start -->
        <a-form-model-item
          prop="adminNameAd"
          class="required-item"
          v-show="sourceForm.type === 'ad'"
        >
          <span slot="label"
            >{{ $t('thirdPart.bindDn') }}
            <a-tooltip
              placement="top"
              :title="$t('thirdPart.rootDnTip2')"
              arrow-point-at-center
            >
              <icon-font type="ic-help" class="ic-help-tip" />
            </a-tooltip>
          </span>
          <a-input
            v-model="sourceForm.adminNameAd"
            :placeholder="$t('common.accountTip')"
            autocomplete="new-password"
          />
        </a-form-model-item>

        <a-form-model-item
          prop="adminNameLdap"
          class="required-item"
          v-if="sourceForm.type === 'ldap'"
        >
          <span slot="label"
            >{{ $t('thirdPart.bindDn') }}
            <a-tooltip
              placement="top"
              :title="$t('thirdPart.rootDnTip')"
              arrow-point-at-center
            >
              <icon-font type="ic-help" class="ic-help-tip" />
            </a-tooltip>
          </span>
          <a-input
            v-model="sourceForm.adminNameLdap"
            :placeholder="$t('thirdPart.ladpNameTip')"
            autocomplete="new-password"
          />
        </a-form-model-item>
        <!-- 绑定账号 end -->

        <!-- 绑定密码 start -->
        <a-form-model-item
          prop="adminPwdAd"
          class="required-item"
          :wrapper-col="{ offset: 10 }"
          v-show="sourceForm.type === 'ad'"
        >
          <span slot="label">{{ $t('thirdPart.bindPwd') }} </span>
          <a-input-password
            v-model="sourceForm.adminPwdAd"
            :placeholder="$t('common.pwdTip')"
            autocomplete="new-password"
          />
          <a-button
            @click="onTestConn"
            type="primary"
            ghost
            class="conn-test-btn"
            :loading="isLoading"
          >
            {{ $t('thirdPart.connTest') }}
          </a-button>
        </a-form-model-item>
        <a-form-model-item
          prop="adminPwdLdap"
          class="required-item"
          :wrapper-col="{ offset: 10 }"
          v-show="sourceForm.type === 'ldap'"
        >
          <span slot="label">
            {{ $t('thirdPart.bindPwd') }}
            <a-tooltip
              placement="top"
              :title="$t('thirdPart.rootPwdTip')"
              arrow-point-at-center
            >
              <icon-font type="ic-help" class="ic-help-tip" />
            </a-tooltip>
          </span>
          <a-input-password
            v-model="sourceForm.adminPwdLdap"
            :placeholder="$t('common.pwdTip')"
            autocomplete="new-password"
          />
          <a-button
            @click="onTestConnLadp"
            type="primary"
            ghost
            class="conn-test-btn"
            :loading="isLoading"
          >
            {{ $t('thirdPart.connTest') }}
          </a-button>
        </a-form-model-item>
        <!-- 绑定密码 end -->

        <LayoutPanel
          class="ldap-sub-wrapper"
          :title="$t('thirdPart.accountAttr')"
          v-show="sourceForm.type === 'ldap'"
        >
          <a-form-model-item prop="userNameAttr">
            <span slot="label">
              {{ $t('thirdPart.userAttr') }}
              <a-tooltip
                placement="top"
                :title="$t('thirdPart.userNameAttrTip')"
                arrow-point-at-center
              >
                <icon-font type="ic-help" class="ic-help-tip" />
              </a-tooltip>
            </span>
            <a-input v-model="sourceForm.userNameAttr" />
          </a-form-model-item>
          <a-form-model-item
            prop="userNameAttr"
            :label="$t('thirdPart.pwdAttr')"
          >
            <a-input v-model="sourceForm.userPwdAttr" />
          </a-form-model-item>
          <a-form-model-item :label="$t('thirdPart.pwdType')">
            <a-select
              v-model="sourceForm.userPwdType"
              :options="ldapPwdTypeOptions"
            >
            </a-select>
          </a-form-model-item>
        </LayoutPanel>
      </div>
      <a-form-model-item style="margin-top: 24px" :wrapper-col="{ offset: 10 }">
        <a-button type="primary" @click="onSave">
          {{ $t('common.save') }}
        </a-button>
      </a-form-model-item>
    </a-form-model>
  </div>
</template>

<script>
import { ValiDateTools } from '@/utils';
import authSysMixin from '@project/authSys/mixin/authSysMixin';
import { requestHttp, maccApi } from '@utils/index';
import _ from 'lodash';
import LayoutPanel from '@views/common/deviceDetail/components/components/layoutPanel.vue';
import { mapState } from 'vuex';

export default {
  name: 'sourceForm',
  mixins: [authSysMixin],
  components: {
    LayoutPanel,
  },
  props: {
    record: {
      typeof: Object,
      default: () => {
        return null;
      },
    },
  },
  data() {
    return {
      isLoading: false,
      statusTxt: this.$t('common.enable'),
      sourceForm: {
        statusBool: true,
        status: 1,
        name: '', // '',
        type: 'ad',
        ldapIp: '',
        rootDn: '',
        serverDomain: '', //'auth.com',
        serverIp: '', // '172.29.45.173',
        serverPort: 389, // 389,
        adminName: 'administrator', // 'administrator', // '',
        adminNameAd: 'administrator', // 'administrator', // '',
        adminNameLdap: 'administrator', // 'administrator', // '',
        adminPwd: '', //'fw123!@#', // '',
        adminPwdAd: '',
        adminPwdLdap: '',
        userNameAttr: 'uid',
        userPwdAttr: 'userPassword',
        userPwdType: '',
        // serverDomain: '', // auth.com,
        // serverIp: '', // 172.29.45.173,
        // serverPort: null, // 389,
        // adminName: '', // administrator,
        // adminPwd: '', // fw123!@#,
      },

      formRuleObj: {
        name: [
          {
            message: this.$t('common.byteRange', [32]),
            max: 32,
            trigger: 'blur',
          },
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
        ],
        type: [
          {
            required: true,
            trigger: 'change',
          },
        ],
        serverDomain: [
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
        ],
        serverIp: [
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
          { validator: this.validateIp, trigger: 'blur' },
        ],
        serverPort: [
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
          { validator: this.validatePort, trigger: 'blur' },
        ],
        ldapIp: [
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
          { validator: this.validateIp, trigger: 'blur' },
        ],
        ldapPort: [
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
          { validator: this.validatePort, trigger: 'blur' },
        ],
        rootDn: [
          {
            required: true,
            message: this.$t('common.mustEnter'),
            trigger: 'blur',
          },
        ],
        adminNameAd: [
          {
            message: this.$t('common.byteRange', [32]),
            max: 32,
            trigger: 'blur',
          },
          { validator: this.validateAd, trigger: 'blur' },
        ],
        adminNameLdap: [
          {
            message: this.$t('common.byteRange', [32]),
            max: 32,
            trigger: 'blur',
          },
          { validator: this.validateLdap, trigger: 'blur' },
        ],
        adminPwdAd: [
          {
            message: this.$t('common.byteRange', [32]),
            max: 32,
            trigger: 'blur',
          },
          { validator: this.validateAd, trigger: 'blur' },
        ],
        adminPwdLdap: [
          {
            message: this.$t('common.byteRange', [32]),
            max: 32,
            trigger: 'blur',
          },
          { validator: this.validateLdap, trigger: 'blur' },
        ],
        userNameAttr: [
          {
            message: this.$t('common.byteRange', [32]),
            max: 32,
            trigger: 'blur',
          },
        ],
      },
    };
  },
  computed: {
    ...mapState('AuthCommon', ['ldapPasswordTypes']),
    ldapPwdTypeOptions() {
      const tempOptions = [];
      for (const pwdType of this.ldapPasswordTypes) {
        tempOptions.push({
          label: pwdType.value,
          value: pwdType.key,
        });
      }
      return tempOptions;
    },
  },
  watch: {
    'sourceForm.statusBool': {
      handler(value) {
        if (value) {
          this.sourceForm.status = 1;
          this.statusTxt = this.$t('common.enable');
        } else {
          this.sourceForm.status = 0;
          this.statusTxt = this.$t('common.disable');
        }
      },
    },
    record: {
      handler(value) {
        if (value) {
          if (value.status) {
            value.statusBool = true;
          } else {
            value.statusBool = false;
          }
          value.serverPort = value.serverPort || 389;
          value.adminName = value.adminName || 'administrator';
          value.adminNameAd = value.adminNameAd || 'administrator';
          value.userNameAttr = value.userNameAttr || 'uid';
          value.userPwdAttr = value.userPwdAttr || 'userPassword';

          this.sourceForm = _.cloneDeep(value);
          this.$set(this.sourceForm, 'type', value.type || 'ad');

          if (this.sourceForm.type === 'ldap') {
            this.$set(this.sourceForm, 'ldapIp', this.sourceForm.serverIp);
            this.$set(this.sourceForm, 'ldapPort', this.sourceForm.serverPort);
            this.$set(
              this.sourceForm,
              'adminNameLdap',
              this.sourceForm.adminName
            );
            this.$set(
              this.sourceForm,
              'adminPwdLdap',
              this.sourceForm.adminPwd
            );
          } else {
            this.$set(
              this.sourceForm,
              'adminNameAd',
              this.sourceForm.adminName
            );
            this.$set(this.sourceForm, 'adminPwdAd', this.sourceForm.adminPwd);
          }
        }

        if (!value.userPwdType && this.ldapPasswordTypes.length > 0) {
          this.$set(
            this.sourceForm,
            'userPwdType',
            this.ldapPasswordTypes[0].value
          );
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    onSave() {
      this.$emit('saveForm');
    },

    async onGetDn() {
      const params = {
        serverIp: this.sourceForm.ldapIp,
        serverPort: this.sourceForm.ldapPort,
      };

      if (params.serverIp === '' || params.serverPort === '') {
        this.$message.warning(this.$t('thirdPart.ldapIpAndPortTip'));
        return false;
      }

      this.isLoading = true;
      const self = this;
      const ret = await this.requestHttpAuth({
        api: maccApi.MACC_SOURCE_DN_POST_API,
        method: 'POST',
        params,
      });
      this.isLoading = false;
      if (ret?.data?.success) {
        this.$message.success(this.$t('thirdPart.getSnSuccess'));
        this.$set(this.sourceForm, 'rootDn', ret?.data?.result);
        this.$refs.rootDnRef.focus();
      } else {
        this.$message.warning(this.$t('thirdPart.getSnFail', [ret?.data?.msg]));
      }
    },

    async onTestConnLadp() {
      const params = {
        type: this.sourceForm.type,
        rootDn: this.sourceForm.rootDn,
        adminName: this.sourceForm.adminNameLdap,
        adminPwd: this.sourceForm.adminPwdLdap,
        serverIp: this.sourceForm.ldapIp,
        serverPort: this.sourceForm.ldapPort,
      };

      if (
        params.type === '' ||
        params.serverDomain === '' ||
        params.serverIp === '' ||
        params.serverPort === ''
      ) {
        this.$message.warning(this.$t('thirdPart.testTip'));
        return false;
      }

      this.isLoading = true;
      const self = this;
      const ret = await this.requestHttpAuth({
        api: maccApi.MACC_SOURCE_TEST_POST_API,
        method: 'POST',
        params,
      });
      this.isLoading = false;
      if (ret?.data?.result?.success) {
        this.$success({
          title: this.$t('thirdPart.connSuccess'),
          // JSX support
          content: <div></div>,
        });
      } else {
        this.$error({
          title: this.$t('thirdPart.connFail'),
          // JSX support
          content: <div></div>,
        });
      }
    },

    async onTestConn() {
      const params = {
        type: this.sourceForm.type,
        serverDomain: this.sourceForm.serverDomain,
        adminName: this.sourceForm.adminNameAd,
        adminPwd: this.sourceForm.adminPwdAd,
        serverIp: this.sourceForm.serverIp,
        serverPort: this.sourceForm.serverPort,
      };

      if (
        params.type === '' ||
        params.serverDomain === '' ||
        params.serverIp === '' ||
        params.serverPort === ''
      ) {
        this.$message.warning(this.$t('thirdPart.testTip'));
        return false;
      }

      this.isLoading = true;
      const self = this;
      const ret = await this.requestHttpAuth({
        api: maccApi.MACC_SOURCE_TEST_POST_API,
        method: 'POST',
        params,
      });
      this.isLoading = false;
      if (ret?.data?.result?.success) {
        this.$success({
          title: this.$t('thirdPart.connSuccess'),
          // JSX support
          content: <div></div>,
        });
      } else {
        this.$error({
          title: this.$t('thirdPart.connFail'),
          // JSX support
          content: <div></div>,
        });
      }
    },

    // 校验Ad的name和password
    validateAd(rule, value, callback) {
      if (this.sourceForm.type === 'ad') {
        if (!value) {
          return callback(new Error(this.$t('common.mustEnter')));
        }
      }
      callback();
    },

    // 校验Ldap的name和password
    validateLdap(rule, value, callback) {
      if (this.sourceForm.type === 'ldap') {
        if (!value) {
          return callback(new Error(this.$t('common.mustEnter')));
        }
      }
      callback();
    },

    // 校验IP
    validateIp(rule, value, callback) {
      const { result, msg } = ValiDateTools.checkIpOnEweb(value);
      if (!result) {
        return callback(new Error(msg));
      }
      callback();
    },

    // 校验IP
    validatePort(rule, value, callback) {
      let num = Number(value);
      if (!/(^[1-9]([0-9]*)$|^[0-9]$)/.test(value)) {
        return callback(new Error(this.$t('common.portRange')));
      }

      if (1 <= value && value <= 65535) {
        return callback();
      } else {
        return callback(new Error(this.$t('common.portRange')));
      }
    },
    getModel() {
      return new Promise((resolve) => {
        const paramForm = _.cloneDeep(this.sourceForm);
        if (paramForm.type === 'ad') {
          paramForm.adminName = paramForm.adminNameAd;
          paramForm.adminPwd = paramForm.adminPwdAd;
        } else {
          // ldap
          paramForm.adminName = paramForm.adminNameLdap;
          paramForm.adminPwd = paramForm.adminPwdLdap;
        }
        delete paramForm.adminNameAd;
        delete paramForm.adminPwdAd;
        delete paramForm.adminNameLdap;
        delete paramForm.adminPwdLdap;

        if (paramForm.statusBool) {
          paramForm.status = 1;
        } else {
          paramForm.status = 0;
          resolve(this.sourceForm);
        }
        this.$refs.sourceFormRef.validate((valid) => {
          if (!valid) {
            resolve(null);
            return false;
          }

          resolve(paramForm);
        });
      });
    },
  },
};
</script>

<style lang="less" scoped>
@import url('@/project/authSys/assets/skin/common.less');
.private-common-wrapper {
  .ldap-sub-wrapper {
    /deep/.layout-panel-head {
      display: flex !important;
      font-size: 14px;
    }
    /deep/.layout-panel-head::before {
      display: block !important;
      content: '';
      width: 4px;
      height: 14px;
      background-color: @theme-color;
      margin-right: 8px;
    }
  }
}
.source-type {
  padding: 0 8px;
  font-size: 12px;
  line-height: 20px;
  border-radius: 2px;
  display: inline-block;
  &.ad {
    color: @theme-color;
    background: @theme-light;
  }
  &.ldap {
    color: @success-color;
    background: @success-light;
  }
}
.conn-test-btn {
  position: absolute;
  top: -6px;
  left: 366px;
}
.username-attr {
  color: @gray-7;
  white-space: nowrap;
}
</style>
